package threaddemo12;

import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by L.jp
 * Description:
 * User: 86189
 * Date: 2022-08-06
 * Time: 23:21
 */
/*虽然我们可以理解同步代码块和同步方法的锁对象问题，但是我们并没有直接看到在哪里加上了锁，在哪里释放了
        锁，为了更清晰的表达如何加锁和释放锁，JDK5以后提供了一个新的锁对象Lock
        Lock是接口不能直接实例化，这里采用它的实现类ReentrantLock来实例化*/

//使用更加直观的加锁释放锁来实现线程同步
public class SellTicket implements Runnable {
    //定义初始票数
    private int ticket = 100;
    private final Object object = new Object(); //锁对象
    ReentrantLock reentrantLock = new ReentrantLock();
    
    @Override
    public void run() {
        while (true) {
//            synchronized (object) {  //多个线程使用同一把锁
            try {
                //加锁
                reentrantLock.lock();
                //判断，如果票数小于等于0就停止售卖
                if (ticket <= 0) {
                    break;
                } else {
                    //正常的出票需要时间
                    Thread.sleep(50);
                    //售票后票数--
                    ticket--;
                    //打印窗口还剩多少张、
                    System.out.println(Thread.currentThread().getName() + "在卖票，还剩" + ticket + "张");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //必须保证一定要释放锁，所以放在finally里
                //解锁
                reentrantLock.unlock();
            }
        }
//        }
    }
}
